package br.com.gbvbahia.mybooks.service.ws;

import java.util.Date;

import org.apache.commons.lang3.StringUtils;
import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.PropertyInfo;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapPrimitive;
import org.ksoap2.serialization.SoapSerializationEnvelope;

import android.util.Log;
import br.com.gbvbahia.commons.modelos.EntityInterface;
import br.com.gbvbahia.commons.ws.WSCommons;
import br.com.gbvbahia.mybooks.ActivityMae;
import br.com.gbvbahia.mybooks.dao.PerfilDAO;
import br.com.gbvbahia.mybooks.modelos.PerfilVO;
import br.com.gbvbahia.mybooks.service.ws.WebService.RetornosWS;

/**
 * Default acesso somente pela WebService. WS responsavel pelo tratamento WS
 * referente a perfil.
 * 
 * @author Guilherme
 * 
 */
class PerfilService {
	private String NAMESPACE = "http://ws.bookmy.gbvbahia.com.br/";
	private String URL = WebService.URL_SERVIDOR + "/ws/perfil?wsdl";

	protected static int atualizarPerfil(String perfil, String newEmail,
			String newSenha, PerfilDAO dao) {
		if (StringUtils.isBlank(perfil) || StringUtils.isBlank(newEmail)
				|| StringUtils.isBlank(newSenha)) {
			return WebService.EMAIL_SENHA_INVALIDO;
		}
		PerfilVO pvo = dao.getPerfil();
		int wsResult = new PerfilService().new AtualizarPerfil()
				.atualizarPerfil(perfil, pvo.getId(), newEmail, newSenha);
		switch (wsResult) {
		case WebService.RetornosWS.SUCESSO:
			pvo.setEmail(newEmail);
			pvo.setSenha(newSenha);
			dao.update(pvo);
			return WebService.PERFIL_ATUALIZADO;
		case WebService.RetornosWS.EMAIL_EXISTE:
			return WebService.PERFIL_EMAIL_VINCLULO_ERRO;
		case WebService.RetornosWS.DADOS_INVALIDOS:
		default:
			return WebService.EMAIL_SENHA_INVALIDO;
		}
	}

	protected static int recuperarSenha(String email) {
		int wsResult = new PerfilService().new RecuperarDados()
				.recuperarDados(email);
		switch (wsResult) {
		case WebService.RetornosWS.PERFIL_NAO_ENCONTRADO:
			return WebService.EMAIL_NAO_ENCONTRADO;
		case WebService.RetornosWS.SUCESSO:
			return WebService.EMAIL_RECUPERACAO_ENVIADO;
		default:
			return WebService.ERRO_DESCONHECIDO;
		}
	}

	/*
	 * LiberarMobilePerfilWS
	 */
	protected static int carregarPerfil(String perfil, String senha,
			String email, PerfilDAO dao) {
		PerfilVO perfilBd = dao.getPerfil();
		if (perfilBd == null) {
			perfilBd = new PerfilVO();
		}
		perfilBd.setPerfil(perfil);
		perfilBd.setEmail(email);
		perfilBd.setSenha(senha);
		perfilBd.setSalvoWS(EntityInterface.FALSE);
		dao.insertPrepare(perfilBd);
		PerfilService.LiberarMobilePerfilWS perfilWS = new PerfilService().new LiberarMobilePerfilWS();
		String retrunWS = perfilWS.liberarMobile(perfil, senha, email,
				perfilBd.getId());
		if (StringUtils.contains(retrunWS, "@")) {
			perfilBd.setEmail(retrunWS);
			perfilBd.setSalvoWS(EntityInterface.TRUE);
			dao.update(perfilBd);
			return WebService.PERFIL_CARREGADO_OK;
		} else if (StringUtils.equals(retrunWS,
				Integer.toString(WebService.RetornosWS.LOGIN_SENHA_INCORRETO))) {
			return WebService.PERFIL_EMAIL_SENHA_INCORRETA;
		}
		return WebService.ERRO_DESCONHECIDO;
	}

	/**
	 * Deverá solicitar ao WebServie que crie o perfil enviado.
	 * 
	 * @param perfil
	 * @param email
	 * @return
	 */
	protected static int criarPerfil(String perfil, String email,
			PerfilDAO perfilDao) {
		PerfilVO vo = new PerfilVO();
		vo.setDataAlteracao(new Date().getTime());
		vo.setEmail(email);
		vo.setPerfil(perfil);
		vo.setSenha(null);
		perfilDao.insertPrepare(vo);
		PerfilService.CriarPerfilWS perfilWS = new PerfilService().new CriarPerfilWS();
		int pass = perfilWS.inserirPerfil(vo.getPerfil(), vo.getEmail(),
				vo.getId());
		switch (pass) {
		case RetornosWS.PERFIL_EXISTE:
			return tratarExistente(perfilDao, vo,
					new PerfilService().new RecuperarSenha());
		case RetornosWS.EMAIL_INVALIDO:
			return WebService.EMAIL_INVALIDO;
		case RetornosWS.EMAIL_EXISTE:
			return WebService.EMAIL_EXISTE;
		case RetornosWS.ERRO_DESCONHECIDO:
			return WebService.ERRO_DESCONHECIDO;
		default:
			if (pass > 100000) {
				vo.setSenha(Integer.toString(pass));
				vo.setSalvoWS(EntityInterface.TRUE);
				perfilDao.update(vo);
				return WebService.PERFIL_CRIADO_OK;
			} else {
				return WebService.ERRO_DESCONHECIDO;
			}
		}
	}

	/**
	 * Se o perfil já está cadastrado, faz uma tentaviva de recuperar a senha
	 * pelo id perfil no aparelho, login usuario e e mail do usuário.
	 * 
	 * @param perfilDao
	 * @param vo
	 * @param perfilWS
	 * @return
	 */
	private static int tratarExistente(PerfilDAO perfilDao, PerfilVO vo,
			PerfilService.RecuperarSenha perfilWS) {
		String senhaLost = perfilWS.recuperarSenha(vo.getPerfil(),
				vo.getEmail(), vo.getId());
		if (senhaLost == null
				|| senhaLost.equals(Integer
						.toString(WebService.RetornosWS.PERFIL_NAO_ENCONTRADO))) {
			return WebService.PERFIL_JA_EXISTENTE;
		} else if (Integer.toString(WebService.RetornosWS.ERRO_DESCONHECIDO)
				.equals(senhaLost)) {
			return WebService.ERRO_DESCONHECIDO;
		} else {
			vo.setSenha(senhaLost);
			vo.setSalvoWS(EntityInterface.TRUE);
			perfilDao.update(vo);
			return WebService.PERFIL_CRIADO_OK;
		}
	}

	/**
	 * 
	 * NAMESPACE: Namespace e o targetNamespace no WSDL.
	 * 
	 * URL: A URL do WSDL. Seu valor e o atributo location do elemento
	 * soap:address referente a um elemento port em um WSDL. A nao ser que o
	 * servico da Web tambem esteja hospedado no dispositivo Android, o nome do
	 * host nao deve ser especificado como localhost, porque o aplicativo
	 * executa no dispositivo Android, enquanto o servico da Web esta hospedado
	 * no servidor localhost . Especifique o nome de host como o endereco IP do
	 * servidor que hospeda o servico da Web.
	 * 
	 * METHOD_NAME: Nome da operacao do servico da Web, que pode ser obtido a
	 * partir do WSDL.
	 * 
	 * SOAP_ACTION: NAMESPACE+METHOD_NAME especificado com um literal de cadeia
	 * de caractere.
	 * 
	 * Copy from:
	 * http://www.ibm.com/developerworks/br/library/ws-android/index.html
	 * 
	 * @author Guilherme
	 */
	private class CriarPerfilWS extends WSCommons {
		private String METHOD_NAME = "inserirPerfil";
		private String SOAP_ACTION = NAMESPACE + METHOD_NAME;

		public int inserirPerfil(String perfil, String email, String idMobile) {
			try {
				SoapObject soap = new SoapObject(NAMESPACE, METHOD_NAME);
				makeProperty(perfil, "perfil", soap, PropertyInfo.STRING_CLASS);
				makeProperty(email, "email", soap, PropertyInfo.STRING_CLASS);
				makeProperty(idMobile, "idMobile", soap,
						PropertyInfo.STRING_CLASS);
				makeProperty("sal", "sal", soap, PropertyInfo.STRING_CLASS);
				SoapSerializationEnvelope envelope = getEnvelope(
						SoapEnvelope.VER11, soap, URL, SOAP_ACTION);
				SoapPrimitive resultsRequestSOAP = (SoapPrimitive) envelope
						.getResponse();
				return Integer.valueOf(resultsRequestSOAP.toString());
			} catch (Exception e) {
				Log.e(ActivityMae.LOG_TAG, "WS Erro: " + METHOD_NAME + " ==> ",
						e);
				return RetornosWS.ERRO_DESCONHECIDO;
			}
		}
	}

	private class RecuperarSenha extends WSCommons {
		private String METHOD_NAME = "recuperarSenha";
		private String SOAP_ACTION = NAMESPACE + METHOD_NAME;

		public String recuperarSenha(String perfil, String email,
				String idMobile) {
			try {
				SoapObject soap = new SoapObject(NAMESPACE, METHOD_NAME);
				makeProperty(perfil, "perfil", soap, PropertyInfo.STRING_CLASS);
				makeProperty(email, "email", soap, PropertyInfo.STRING_CLASS);
				makeProperty(idMobile, "idMobile", soap,
						PropertyInfo.STRING_CLASS);
				makeProperty("sal", "sal", soap, PropertyInfo.STRING_CLASS);
				SoapSerializationEnvelope envelope = getEnvelope(
						SoapEnvelope.VER11, soap, URL, SOAP_ACTION);
				return ((SoapPrimitive) envelope.getResponse()).toString();
			} catch (Exception e) {
				Log.e(ActivityMae.LOG_TAG, "WS Erro: " + METHOD_NAME + " ==> ",
						e);
				return Integer.toString(RetornosWS.ERRO_DESCONHECIDO);
			}
		}
	}

	private class LiberarMobilePerfilWS extends WSCommons {
		private String METHOD_NAME = "liberarMobile";
		private String SOAP_ACTION = NAMESPACE + METHOD_NAME;

		public String liberarMobile(String perfil, String senha, String email,
				String idMobile) {
			try {
				SoapObject soap = new SoapObject(NAMESPACE, METHOD_NAME);
				makeProperty(perfil, "perfil", soap, PropertyInfo.STRING_CLASS);
				makeProperty(senha, "senha", soap, PropertyInfo.STRING_CLASS);
				makeProperty(email, "email", soap, PropertyInfo.STRING_CLASS);
				makeProperty(idMobile, "idMobile", soap,
						PropertyInfo.STRING_CLASS);
				makeProperty("sal", "sal", soap, PropertyInfo.STRING_CLASS);
				SoapSerializationEnvelope envelope = getEnvelope(
						SoapEnvelope.VER11, soap, URL, SOAP_ACTION);
				return ((SoapPrimitive) envelope.getResponse()).toString();
			} catch (Exception e) {
				Log.e(ActivityMae.LOG_TAG, "WS Erro: " + METHOD_NAME + " ==> ",
						e);
				return Integer.toString(RetornosWS.ERRO_DESCONHECIDO);
			}
		}
	}

	private class RecuperarDados extends WSCommons {
		private String METHOD_NAME = "recuperarDados";
		private String SOAP_ACTION = NAMESPACE + METHOD_NAME;

		public int recuperarDados(String email) {
			try {
				SoapObject soap = new SoapObject(NAMESPACE, METHOD_NAME);
				makeProperty(email, "email", soap, PropertyInfo.STRING_CLASS);
				makeProperty("sal", "sal", soap, PropertyInfo.STRING_CLASS);
				SoapSerializationEnvelope envelope = getEnvelope(
						SoapEnvelope.VER11, soap, URL, SOAP_ACTION);
				return Integer.valueOf(((SoapPrimitive) envelope.getResponse())
						.toString());
			} catch (Exception e) {
				Log.e(ActivityMae.LOG_TAG, "WS Erro: " + METHOD_NAME + " ==> ",
						e);
				return RetornosWS.ERRO_DESCONHECIDO;
			}
		}
	}

	private class AtualizarPerfil extends WSCommons {
		private String METHOD_NAME = "atualizarPerfil";
		private String SOAP_ACTION = NAMESPACE + METHOD_NAME;

		public int atualizarPerfil(String perfil, String idMobile,
				String email, String senha) {
			try {
				SoapObject soap = new SoapObject(NAMESPACE, METHOD_NAME);
				makeProperty(perfil, "perfil", soap, PropertyInfo.STRING_CLASS);
				makeProperty(idMobile, "idMobile", soap,
						PropertyInfo.STRING_CLASS);
				makeProperty(email, "email", soap, PropertyInfo.STRING_CLASS);
				makeProperty(senha, "senha", soap, PropertyInfo.STRING_CLASS);
				makeProperty("sal", "sal", soap, PropertyInfo.STRING_CLASS);
				SoapSerializationEnvelope envelope = getEnvelope(
						SoapEnvelope.VER11, soap, URL, SOAP_ACTION);
				return Integer.valueOf(((SoapPrimitive) envelope.getResponse())
						.toString());
			} catch (Exception e) {
				Log.e(ActivityMae.LOG_TAG, "WS Erro: " + METHOD_NAME + " ==> ",
						e);
				return RetornosWS.ERRO_DESCONHECIDO;
			}
		}
	}
}
